package com.yanxi.yxregiserve.web.grpc.impl;

import com.yanxi.yxregiserve.web.common.constant.GrpcConstants;
import com.yanxi.yxregiserve.web.domin.system.ClientExample;
import com.yanxi.yxregiserve.web.grpc.RegisterService.RegisterRequest;
import com.yanxi.yxregiserve.web.grpc.RegisterService.RegisterResponse;
import com.yanxi.yxregiserve.web.grpc.RegisterService.RegisterServiceGrpc;
import com.yanxi.yxregiserve.web.service.system.ClientExampleService;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Collectors;

@GrpcService
public class RegisterServiceImpl extends RegisterServiceGrpc.RegisterServiceImplBase {

    @Autowired
    private ClientExampleService clientExampleService;

    private static final Logger logger = Logger.getLogger(RegisterServiceImpl.class.getName());

    @Override
    public void registerClient(RegisterRequest request, StreamObserver<RegisterResponse> responseStreamObserver){

        /**
         * 查询 端口+内网地址
         * 检测 serType!=2
         */
        List<ClientExample> list =
                clientExampleService.selectTList(
                        ClientExample
                                .builder()
                                .port(request.getPort())
                                .inNetIp(request.getInNetIp()).build()
                );
        List<ClientExample> clientExamples = list.stream().filter(it -> !"2".equals(it.getSerType())).collect(Collectors.toList());


        if (!ObjectUtils.isEmpty(clientExamples)) {

            /**
             * 说明同一网段 同一端口 有超过两台实例同时在线
             * 系统异常
             */
            if(clientExamples.size() > 1){

                logger.warning("同实例多条在线，系统异常，请及时排查。");

                responseStreamObserver.onNext(RegisterResponse.newBuilder()
                        .setStatus(GrpcConstants.RPC_FAIL_CODE)
                        .setMsg(GrpcConstants.RPC_FAIL)
                        .build());

                responseStreamObserver.onCompleted();

            }

            /**
             * 拿到这台实例
             */
            ClientExample client= clientExamples.get(0);

            /**
             * 说明是在心跳检测期间重新启动。
             * 注销这台实例.
             *
             * Mysql client 这条数据
             * deathTime 改为现在时间
             * serType 改为 2
             *
             */
            client.setDeathTime(new Date());
            client.setSerType("2");
            clientExampleService.updateT(client);

            /**
             * Mysql 中新增一台实例
             */
            clientExampleService.insertT(
                    ClientExample.builder()
                            .projectName(request.getProjectName())
                            .port(request.getPort())
                            .callbackInterface(request.getCallbackInterface())
                            .inNetIp(request.getInNetIp())
                            .regSerTime(new Date())
                            .serType("0")
                            .build()
            );

        } else {

            /**
             * Mysql 中新增一台实例
             */
            clientExampleService.insertT(
                    ClientExample.builder()
                            .projectName(request.getProjectName())
                            .port(request.getPort())
                            .callbackInterface(request.getCallbackInterface())
                            .inNetIp(request.getInNetIp())
                            .regSerTime(new Date())
                            .serType("0")
                            .build()
            );
        }


        /**
         * 成功返回
         */
        responseStreamObserver.onNext(RegisterResponse.newBuilder()
                .setStatus(GrpcConstants.RPC_SUCCESS_CODE)
                .setMsg(GrpcConstants.RPC_SUCCESS)
                .build());

        responseStreamObserver.onCompleted();
    }

}
